#ifndef __SERVICE_CLIENT_H__
#define __SERVICE_CLIENT_H__

#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <list>

class ServiceClient : public boost::enable_shared_from_this<ServiceClient>
{
public:
	typedef std::shared_ptr<boost::asio::io_service> service_ptr;
	typedef std::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
	typedef boost::shared_ptr<std::vector<unsigned char> > buffer_ptr;
	typedef buffer_ptr::element_type::iterator iter_type;

	virtual void setInfo(const int connectPort, const std::wstring descIp, const int descPort, const std::wstring srcIp, const int srcPort);
	virtual bool start();
	virtual void stop();
protected:
	virtual void handleThread(service_ptr pService, const int connectPort, const std::string descIp, const int descPort, const std::string srcIp, const int srcPort);
	virtual std::string frame2string(buffer_ptr pBuffer, unsigned int count);
	virtual std::string wcs2str(const std::wstring& str);
	virtual bool queryChannel(const int descPort, socket_ptr pSocket);
	virtual void handleReadSrc(const boost::system::error_code& ec, size_t Count, buffer_ptr pBuffer, socket_ptr pSocket);
	virtual void handleReadDesc(const boost::system::error_code& ec, size_t Count, buffer_ptr pBuffer, socket_ptr pSocket);
	virtual void handleWriteSrc(const boost::system::error_code& ec, size_t Count, buffer_ptr pBuffer);
	virtual void handleWriteDesc(const boost::system::error_code& ec, size_t Count, buffer_ptr pBuffer);
	virtual unsigned char calCrc(iter_type IterStart, iter_type IterEnd);
	virtual std::string error2str(const unsigned char errorCode);

	service_ptr m_pService;
	boost::thread m_thread;
	socket_ptr m_pSocketSrc;
	socket_ptr m_pSocketDesc;
	std::wstring m_DescIp;
	int m_DescPort;
	std::wstring m_SrcIp;
	int m_SrcPort;
	int m_ConnectPort;
	bool m_bCreateChannel;
	std::list<std::pair<buffer_ptr, unsigned int> > m_ListSrc;
	std::list<std::pair<buffer_ptr, unsigned int> > m_ListDesc;
};
typedef boost::shared_ptr<ServiceClient> ServiceClientPtr;


#endif


